-- UIFateChainEffect
-- Create by cheny3 Dec/07/2016
-- 命运的链效果

-- UIFateChain继承自Layer
UIFateChainEffect = class("UIFateChainEffect", function()
    return cc.Layer:create();
end);

local BASE_SCALE  = 0.65;  -- 基础缩放

function UIFateChainEffect.create(info, callback)
    return UIFateChainEffect.new(info, callback);
end

-- 构造函数
function UIFateChainEffect:ctor(info, callback)
    -- 初始化
    self:setName("UIFateChainEffect");
    local node = cc.CSLoader:createNode("layout/fate_chain/FateChainEffect.csb");
    self:addChild(node);
    self.node = node;

    self.info = info;
    self.callback = callback;

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIFateChainEffect:resize()
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local node = self.node;

    -- bg置于中间并缩放至合适大小
    AlignM.alignToCenter(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 重绘
function UIFateChainEffect:redraw()
    local hero1Node = findChildByName(self.node, "CT/hero1");
    local hero2Node = findChildByName(self.node, "CT/hero2");
    local dialog1 = findChildByName(hero1Node, "dialog");
    local dialog2 = findChildByName(hero2Node, "dialog");
    local icon1 = findChildByName(dialog1, "icon");
    local icon2 = findChildByName(dialog2, "icon");
    local effectNode = findChildByName(self.node, "CT/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/effect_node2");
    effectNode2:setVisible(false);

    local answerPet = self.info["answer_pet"];
    local requestPet = self.info["request_pet"];

    if self.info["request_rid"] == ME.user.rid then
        -- 请求方
        local modelId

        -- 对方的模型
        if tonumber(self.info["activity_costume"]) > 0 then
            -- 时装
            modelId = EquipM.query(self.info["activity_costume"], "dbase")["pet_model_id"];
        else
            -- 用默认
            modelId = PetM.query(answerPet, "default_model");
        end
        local animaNode = HeroDisplay.create(modelId);
        hero1Node:addChild(animaNode);
        hero1Node.animaNode = animaNode;

        -- 自己的模型
        local pet = PetM.getMyPet(requestPet);
        modelId = pet:getModelId();
        animaNode = HeroDisplay.create(modelId);
        hero2Node:addChild(animaNode);
        hero2Node.animaNode = animaNode;
    else
        -- 回答方

        -- 自己的模型
        local pet = PetM.getMyPet(answerPet);
        local modelId = pet:getModelId();
        local animaNode = HeroDisplay.create(modelId);
        hero2Node:addChild(animaNode);
        hero2Node.animaNode = animaNode;

        -- 对方的模型
        if tonumber(self.info["activity_costume"]) > 0 then
            -- 时装
            modelId = EquipM.query(self.info["activity_costume"], "dbase")["pet_model_id"];
        else
            -- 用默认
            modelId = PetM.query(requestPet, "default_model");
        end
        animaNode = HeroDisplay.create(modelId);
        hero1Node:addChild(animaNode);
        hero1Node.animaNode = animaNode;
    end

    hero1Node.animaNode:setScale(BASE_SCALE);
    hero2Node.animaNode:setScale(-BASE_SCALE, BASE_SCALE);
    hero1Node.animaNode:setLocalZOrder(-1);
    hero2Node.animaNode:setLocalZOrder(-1);
    hero1Node.animaNode:setPosition(90, 100);
    hero2Node.animaNode:setPosition(90, 100);

    -- 对话框提示图标
    -- TODO暂时都先用感叹号
    local iconPathList = {getWorkshopIconPath("guide/exclamation_mark"), getFateChainIconPath("heart")};
    if false and type(self.info["show_id"]) == "number"
        and FateChainM.queryGroup(self.info["show_id"], "type") == FATE_CHAIN_TYPE_LOVER then
        -- 恋人类型的用心
        iconPath = iconPathList[2];
    else
        -- 其他类型的要感叹号
        iconPath = iconPathList[1];
    end

    icon1:loadTexture(iconPath);
    icon2:loadTexture(iconPath);
    dialog1:setPosition(cc.p(35, 145));
    dialog2:setPosition(cc.p(160, 145));
    dialog1:setVisible(false);
    dialog2:setVisible(false);
    hero1Node.animaNode:setVisible(false);
    hero2Node.animaNode:setVisible(false);

    self:fateEffect();
end

-- 链接特效3(左边不动，右边跳入)
function UIFateChainEffect:fateEffect3()
    local hero1Node = findChildByName(self.node, "CT/hero1");
    local hero2Node = findChildByName(self.node, "CT/hero2");
    local dialog1 = findChildByName(hero1Node, "dialog");
    local dialog2 = findChildByName(hero2Node, "dialog");
    local icon1 = findChildByName(dialog1, "icon");
    local icon2 = findChildByName(dialog2, "icon");
    local effectNode = findChildByName(self.node, "CT/effect_node");

    -- 自己直接可见
    hero2Node.animaNode:setVisible(true);
    hero1Node.animaNode:setVisible(true);

    -- 光效
    local function effect()
        effectNode:removeAllChildren();
        self:fateBoomEffect(effectNode);

        local function endEffect()
            self:endEffect();
        end

        if not self.info["fate_id"] then
            performWithDelay(self.node, endEffect, 3);
        else
            performWithDelay(self.node, function() self:newFateEffect(); end, 2);
        end
    end

    -- 左边的直接显示
    dialog2:setVisible(true);
    dialog2:setScale(0.8);
    playBubbleAnima(dialog2, false, 0.8);

    -- 出现对话框
    local function showDialog()
        dialog1:setVisible(true);
        dialog1:setScale(0.8);
        self:appearEffect(dialog1, function() playBubbleAnima(dialog1, false, 0.8) end, 0.45, 0.8);
        performWithDelay(self.node, effect, 1.0);
    end

    -- 对方跳进来
    local jumps = 5;
    local moveX = math.ceil((DESIGN_WIDTH / 2 - hero1Node:getPositionX()) / jumps);
    hero1Node:setPositionX(DESIGN_WIDTH / 2);
    fateChainJumpEffect(hero1Node, moveX, jumps, showDialog);
end

-- 链接特效2（左边右边对话框弹出）
function UIFateChainEffect:fateEffect2()
    local hero1Node = findChildByName(self.node, "CT/hero1");
    local hero2Node = findChildByName(self.node, "CT/hero2");
    local dialog1 = findChildByName(hero1Node, "dialog");
    local dialog2 = findChildByName(hero2Node, "dialog");
    local icon1 = findChildByName(dialog1, "icon");
    local icon2 = findChildByName(dialog2, "icon");
    local effectNode = findChildByName(self.node, "CT/effect_node");

    -- 光效
    local function effect()
        effectNode:removeAllChildren();
        self:fateBoomEffect(effectNode);

        local function endEffect()
            self:endEffect();
        end

        performWithDelay(self.node, endEffect, 3);
    end

    -- 出现对话框
    local function showDialog()
        dialog1:setVisible(true);
        self:appearEffect(dialog1, function() playBubbleAnima(dialog1, false, 1) end, 0.45);
        local function delay()
            dialog2:setVisible(true);
            self:appearEffect(dialog2, function() playBubbleAnima(dialog2, false, 1) end);
            performWithDelay(self.node, effect, 1.0);
        end
        performWithDelay(self.node, delay, 0.25);
    end
    performWithDelay(self.node, showDialog, 0.8);

    local function showHeroModel()
        hero1Node.animaNode:setVisible(true);
        hero2Node.animaNode:setVisible(true);
        self:appearEffect(hero1Node);
        self:appearEffect(hero2Node);
    end
    showHeroModel();
end

-- 弹出效果
function UIFateChainEffect:appearEffect(node, callback, delayTime, scale)
    node:stopAllActions();
    node:setScale(0);

    scale = scale or 1;

    local scaleUp = cc.ScaleTo:create(0.3, 1.3 * scale);
    local scaleDown = cc.ScaleTo:create(0.1, 1 * scale);
    local delay = cc.DelayTime:create(delayTime or 0.1);
    local scaleUp2 = cc.ScaleTo:create(0.1, 1.1 * scale);
    local scaleDown2 = cc.ScaleTo:create(0.1, 1.0 * scale);
    local scaleUp3 = cc.ScaleTo:create(0.3, 1.3 * scale);
    local scaleDown3 = cc.ScaleTo:create(0.1, 0.9 * scale);
    if callback then
        node:runAction(cc.Sequence:create(scaleUp3, scaleDown3, delay, cc.CallFunc:create(callback)));
    else
        node:runAction(cc.Sequence:create(scaleUp, scaleDown, scaleUp2, scaleDown2));
    end
end

-- 效果播放完毕后
function UIFateChainEffect:endEffect()
    if self.callback then
        self.callback();
    end
    UIMgr.getCurrentScene():removeFormByName("UIFateChainEffect");
end

-- 注册事件处理回调函数
function UIFateChainEffect:registerEventCallback()
    -- 注册获得焦点的回调
    EventMgr.register("UIFateChainEffect", event.FOCUS_CHANGED, function(para)
        -- 非初始化获得焦点，BOTTOM向上
        if para["get"] == "UIFateChainEffect" then
        elseif para["lose"] == "UIFateChainEffect" then
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIFateChainEffect 界面析构清理");
            EventMgr.removeAll("UIFateChainEffect");
        elseif eventType == "enter" then

        end
    end);
end

-- 注册点击事件
function UIFateChainEffect:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            self:endEffect();
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_jump_to"));
end

-- 彩球爆开效果
function UIFateChainEffect:fateBoomEffect(node)
    local function frameEventFunc(frame)
        if frame.getEvent and frame:getEvent() == "pilor" then
            local name = frame:getNode():getName();
            local index = frame:getFrameIndex();
            if index == 75 then
                -- 播放到75帧结算
            end
        end
    end
    playEffect(node, 1350, -390, 280, frameEventFunc);
end

-- 达成新链接效果
function UIFateChainEffect:newFateEffect()
    local effectNode = findChildByName(self.node, "CT/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/effect_node2");
    effectNode:setVisible(false);
    effectNode2:setVisible(true);
    local newFateLabel = findChildByName(effectNode2, "new_fate");
    local fateNameLabel = findChildByName(effectNode2, "fate_name");
    newFateLabel:setPositionX(0);
    newFateLabel:removeAllChildren();
    fateNameLabel:setPositionX(0);
    fateNameLabel:setString("");
    fateNameLabel:removeAllChildren();

    local titleStr = getLocStr("new_fate_title");
    local nameStr = FateChainM.queryGroup(self.info["fate_id"], "name");
    local titleFontSize = 73 * getLocFontSizeMulti() * TextStyleM.getTextScale(titleStr, 12);
    local nameFontSize = 53 * getLocFontSizeMulti();
    local maskBgPath = getTextMaskIconPath("text_mask4");
    local maskBgPath2 = getTextMaskIconPath("text_mask2");

    local function fateNameFlyOut()
        local moveOut = cc.MoveTo:create(0.2, cc.p(DESIGN_WIDTH * 1.5, newFateLabel:getPositionY()));
        local moveOut2 = cc.MoveTo:create(0.2, cc.p(-DESIGN_WIDTH * 2, fateNameLabel:getPositionY()));
        newFateLabel:stopAllActions();
        fateNameLabel:stopAllActions();
        newFateLabel:runAction(moveOut);
        fateNameLabel:runAction(moveOut2);
    end

    -- 副本名飞入
    local function fateNameFlyIn()
        playStampEffect(fateNameLabel, nameStr, nameFontSize, fateNameFlyOut, maskBgPath2, { self });
        performWithDelay(self.node, function() self:endEffect(); end, 2.5);
    end

    -- "新关卡出现"飞入
    playFlyInEffect(newFateLabel, titleStr, titleFontSize, fateNameFlyIn, maskBgPath);
end

-- 链接特效1
function UIFateChainEffect:fateEffect()
    local hero1Node = findChildByName(self.node, "CT/hero1");
    local hero2Node = findChildByName(self.node, "CT/hero2");
    local dialog1 = findChildByName(hero1Node, "dialog");
    local dialog2 = findChildByName(hero2Node, "dialog");
    local icon1 = findChildByName(dialog1, "icon");
    local icon2 = findChildByName(dialog2, "icon");
    local effectNode = findChildByName(self.node, "CT/effect_node");

    -- 自己直接可见
    hero2Node.animaNode:setVisible(true);
    hero1Node.animaNode:setVisible(true);

    -- 光效
    local function effect()
        effectNode:removeAllChildren();
        self:fateBoomEffect(effectNode);

        local function endEffect()
            self:endEffect();
        end

        if not self.info["fate_id"] then
            performWithDelay(self.node, endEffect, 3);
        else
            performWithDelay(self.node, function() self:newFateEffect(); end, 2);
        end
    end

    -- 对话框先不不显示
    dialog2:setVisible(false);
    dialog1:setVisible(false);

    -- 右边出现对话框
    local function showDialog()
        local function appearDialog()
            dialog2:setVisible(true);
            dialog2:setScale(0.8);
            self:appearEffect(dialog2, function() playBubbleAnima(dialog2, false, 0.8) end, 0.45, 0.8);
            performWithDelay(self.node, effect, 1.0);
        end
        performWithDelay(self.node, appearDialog, 0.4);
    end

    -- 去除烟尘光效
    local function removeEffect()
        hero1Node:removeChild(hero1Node.effect);
    end

    -- 对方跑进来
    local posX = hero1Node:getPositionX();
    local moveBy = cc.EaseIn:create(cc.MoveTo:create(0.8, cc.p(posX - 10, hero1Node:getPositionY())), 2.4);
    local moveBy2 = cc.MoveTo:create(0.05, cc.p(posX + 10, hero1Node:getPositionY()));
    local moveBy3 = cc.MoveTo:create(0.05, cc.p(posX - 5, hero1Node:getPositionY()));
    local action = cc.Sequence:create(moveBy2, moveBy3);

    local moveBy4 = cc.MoveTo:create(0.05, cc.p(posX + 3, hero1Node:getPositionY()));
    local moveBy5 = cc.MoveTo:create(0.05, cc.p(posX - 3, hero1Node:getPositionY()));
    local moveBy6 = cc.MoveTo:create(0.05, cc.p(posX, hero1Node:getPositionY()));
    local action2 = cc.Sequence:create(moveBy4, moveBy5);
    local shake = cc.Repeat:create(action2, 3);

    local delay = cc.DelayTime:create(0.1);
    hero1Node:setPositionX(DESIGN_WIDTH / 2 + 200);

    -- 烟尘光效
    local function createDustEffect()
        local _, effect = playEffect(hero1Node, 1807, 980, 250, nil, 1.5);
        effect:setScaleX(-1 * effect:getScaleX());
        effect:setLocalZOrder(-100);
        hero1Node.effect = effect;
    end

    hero1Node:runAction(cc.Sequence:create(cc.CallFunc:create(createDustEffect), moveBy,
        action, cc.CallFunc:create(removeEffect), shake, moveBy6, delay, cc.CallFunc:create(showDialog)));
end